package neu.tour.support;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout.LayoutParams;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by lijialin on 16-3-9.
 * 相机预览类
 */
@SuppressWarnings("deprecation")
public class CameraPreview extends SurfaceView
        implements SurfaceHolder.Callback,Camera.AutoFocusCallback {

    private Activity activity;//作用的activity
    public Camera camera; //相机
    public Parameters parameters; //相机参数
    public SurfaceView surfaceView;
    public SurfaceHolder surfaceHolder;
    public float screenWidth; //屏幕宽度
    public float screenHeight; //屏幕高度
    public float surfaceViewHeight;
    private int id;//选中的图片的id

    /**
     * 给CameraActivity用的构造函数
     */
    public CameraPreview(Context context, Activity activity,
                         SurfaceView surfaceView, int id) {
        super(context);
        this.activity = activity;
        this.id = id;
        if(surfaceView!=null) {
            this.surfaceView = surfaceView;
            this.surfaceHolder = surfaceView.getHolder();
            initSurfaceView();
            this.surfaceHolder.addCallback(this);
        }
    }



    /**
     * 初始化SurfaceView
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)//android4.2以上
    private void initSurfaceView() {
        screenWidth  = activity.getWindowManager()
                .getDefaultDisplay().getWidth();
        screenHeight = activity.getWindowManager()
                .getDefaultDisplay().getHeight();
        surfaceViewHeight = (screenWidth/3)*4;
        surfaceView.getLayoutParams().height = (int)surfaceViewHeight;

        Bitmap b = initBorderPic(screenWidth, surfaceViewHeight);//初始化边缘图
        Drawable surfdraw = new BitmapDrawable(b);
        surfaceView.setBackground(surfdraw);//设置边缘图
//        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceHolder.setFixedSize((int)screenWidth, (int)surfaceViewHeight);
        surfaceHolder.setKeepScreenOn(true);// 屏幕常亮

        surfaceView.setOnTouchListener(new ZoomListenter(){
            @Override
            public void zoom(float f){
                int oldzoom = parameters.getZoom();
                int max = parameters.getMaxZoom();
                int newzoom = 0;
                newzoom = (int)(oldzoom + f/10) > max ? max:(int)(oldzoom + f/10);
                newzoom = newzoom < 0 ? 0 : newzoom;
                parameters.setZoom(newzoom);
                camera.setParameters(parameters);
            }

            @Override
            public void autoFocus(MotionEvent event){
                int left = (int)event.getRawX() - 100;
                int top = (int)event.getRawY() - 100;
                final DrawCaptureRect mDraw = new DrawCaptureRect(activity, left, top,
                        200, 200, Color.YELLOW);
                //在一个activity上面添加额外的content
                activity.addContentView(mDraw,
                        new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
                focusOnTouch(event);
                Handler handler=new Handler();
                handler.postDelayed(new Runnable() {
                    public void run() {
                        mDraw.setVisibility(View.INVISIBLE);
                    }
                }, 500);

            }
        });
    }


    /**
     * 初始化边缘图
     */
    public Bitmap initBorderPic(float width, float height) {
        Resources r = getResources();  //获得Resources实例
        Bitmap selectedImg = BitmapFactory.decodeResource(r, id);
        float newHeight =  (width/selectedImg.getWidth())
                * selectedImg.getHeight();// 保持原有比例下的新高度
        HandlePic h = new HandlePic();// 放缩bitmap && 边缘检测
        Bitmap after = h.changeBitmapSize(selectedImg, width, newHeight);
        after = h.getBorder(after);//边缘检测

        int addHeight = (int)(height-newHeight)/2;// 补充图片的高度
        // 构造补充图片
        Bitmap add = Bitmap.createBitmap(
                (int)width, addHeight, Bitmap.Config.ARGB_8888);
        // 构造最后结果图片
        Bitmap result = Bitmap.createBitmap((int)width,
                (int)height, Bitmap.Config.ARGB_8888);

        Paint p = new Paint(); // 构造画笔
        p.setStyle( Paint.Style.STROKE );
        p.setAlpha(0);//设置透明度为0,即全透明
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(add,0, 0, p);// 开始在结果图上绘制
        canvas.drawBitmap(after, 0, add.getHeight(), null);
        canvas.drawBitmap(add,0, add.getHeight()+after.getHeight(), p);
        return result;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        SetAndStartPreview(holder);
    }


    /**
     * 开始在surfaceView上的预览相机画面
     */
    public void SetAndStartPreview(SurfaceHolder holder) {
        try {
            camera = Camera.open();
            camera.setPreviewDisplay(holder);
            camera.setDisplayOrientation(getPreviewDegree(activity));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据手机方向获得相机预览画面旋转的角度
     */
    @TargetApi(Build.VERSION_CODES.FROYO)
    public int getPreviewDegree(Activity activity) {
        // 获得手机的方向
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degree = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degree = 90;
                break;
            case Surface.ROTATION_90:
                degree = 0;
                break;
            case Surface.ROTATION_180:
                degree = 270;
                break;
            case Surface.ROTATION_270:
                degree = 180;
                break;
        }
        return degree;
    }


    public void setCameraParameters(int width, int height) {
        parameters = camera.getParameters(); // 获取各项参数
        parameters.setPictureFormat(PixelFormat.JPEG); // 设置图片格式
        parameters.setJpegQuality(100); // 设置照片质量
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        Size s = getBestSupportedSize(
                parameters.getSupportedPictureSizes(), width, height);
        parameters.setPictureSize(s.width, s.height);//3120 4160
        s = getBestSupportedSize(
                parameters.getSupportedPreviewSizes(), width, height);
        parameters.setPreviewSize(s.width, s.height); // 2224 1668
    }

    @Override
    public void surfaceChanged(SurfaceHolder  holder, int format, int width, int height) {
        setCameraParameters(width, height);
        camera.setParameters(parameters);
        camera.startPreview(); // 开始预览
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (camera != null) {
            camera.release(); // 释放照相机
            camera = null;
        }
    }


    /**
     * 找出最大像素尺寸
     */
    public Size getBestSupportedSize(List<Size> sizes,int w,int h) {
        Size bestSize = sizes.get(0);
        int largestArea = bestSize.width * bestSize.height;
        for (Size s :sizes) {
            if ((float)s.width/(float)s.height == (float)h/(float)w){
                int area = s.width * s.height;
                if (area > largestArea) {
                    bestSize=s;
                    largestArea = area;
                }
            }
        }
        return bestSize;
    }


    /**
     * 以下是触摸对焦部分
     */
    private int clamp(int x, int min, int max) {
        if (x > max) {
            return max;
        }
        if (x < min) {
            return min;
        }
        return x;
    }

    public Camera.Size getResolution() {
        Camera.Parameters params = camera.getParameters();
        Camera.Size s = params.getPreviewSize();
        return s;
    }

    private Rect calculateTapArea(float x, float y, float coefficient) {
        float focusAreaSize = 300;
        int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();
        int centerX = (int) (x / getResolution().width - 1000);
        int centerY = (int) (y / getResolution().height - 1000);
        int left = clamp(centerX - areaSize / 2, -1000, 1000);
        int top = clamp(centerY - areaSize / 2, -1000, 1000);
        RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
        return new Rect(
                Math.round(rectF.left), Math.round(rectF.top),
                Math.round(rectF.right), Math.round(rectF.bottom));
    }


    public void focusOnTouch(MotionEvent event) {
        Rect focusRect = calculateTapArea(event.getRawX(), event.getRawY(), 1f);
        Rect meteringRect = calculateTapArea(event.getRawX(), event.getRawY(), 1.5f);
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

        if (parameters.getMaxNumFocusAreas() > 0) {
            List<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
            focusAreas.add(new Camera.Area(focusRect, 1000));
            parameters.setFocusAreas(focusAreas);
        }

        if (parameters.getMaxNumMeteringAreas() > 0) {
            List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
            meteringAreas.add(new Camera.Area(meteringRect, 1000));
            parameters.setMeteringAreas(meteringAreas);
        }
        camera.setParameters(parameters);
        camera.autoFocus(this);
    }

    @Override
    public void onAutoFocus(boolean arg0, Camera arg1) {}

}
